<script setup>
    import { ref, computed, reactive, onMounted, inject } from 'vue'
    import { Notification, Message } from '@arco-design/web-vue';
    import { useAppInfoListStore } from '@/store/appInfoListStore';
    import { useAppStartLogStore } from '@/store/appStartLogStore';
    import _ from 'lodash'
    
    const { deviceIds, selectedDeviceIds }  = inject('devices')
    let packageNameInfos = ref([])
    const appInfoListStore = useAppInfoListStore()
    const appStartLogStore = useAppStartLogStore()
    const selectedKeys = ref([])
    
    // 初始化appinfo数据
    appInfoListStore.init()
    // 关联appinfo响应式数据
    const data = reactive(appInfoListStore.appInfoList)
    const selectedApps = computed(() => {
      if (!data) return []; // 如果 data 是 undefined，返回一个空数组
      return data.filter(item => {
        if (item && item.key) { // 确保 item 不是 undefined 并且有 key 属性
          return selectedKeys.value.includes(item.key);
        }
        return false; // 如果 item 没有 key 属性，返回 false
      });
    })
    
    // 辅助函数，用于生成随机字符串
    function generateRandomString(length = 10) {
      let result = '';
      const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
      const charactersLength = characters.length;
      for (let i = 0; i < length; i++) {
        result += characters.charAt(Math.floor(Math.random() * charactersLength));
      }
      return result;
    }
    
    const isLogLayoutShowing = ref(false)
    const isAddSelectLoading = ref(false)
    const readPackageNames = async () => {
      isAddSelectLoading.value = true
      packageNameInfos.value = []
      const packageNames = await xapi.getTopPackageName(Array.from(selectedDeviceIds.value))
      if (Array.isArray(packageNames)) {
        for (const pkgName of packageNames) {
          const wholeName = await xapi.getWholeActivity(pkgName.sn, pkgName.packageName)
          packageNameInfos.value.push({
            sn: pkgName.sn,
            packageName: pkgName.packageName,
            wholeName: wholeName
          })
        }
        isAddSelectLoading.value = false
      } else {
        Notification.error({
            title: 'notification',
            content: 'Please read device again or wakeup device first',
            duration: 2500,
        })
        isAddSelectLoading.value = false
      }
    }

    const isAddDialogShowing = ref(false)
    const showAddDialog = () => { 
      readPackageNames()
      isAddDialogShowing.value = true 
      resetFormAppInfo()
    }
    const isEditDialogShowing = ref(false)
    const showEgitDialog = (app) => { 
      currentEditAppInfo = app
      isEditDialogShowing.value = true
    }

    const packageChange = (value) => { 
      formAppInfo.packageName = value
      const result = _.find(packageNameInfos.value, {
        packageName: value
      })
      if (result) {
        formAppInfo.wholeName = result.wholeName
      }
    }

    // add表单数据 v-model
    const formAppInfo = reactive({
      key: generateRandomString(),
      alias: '',
      packageName: '',
      wholeName: '',
    })

    // edit表单数据 v-model
    let currentEditAppInfo = reactive({
      key: '',
      alias: '',
      packageName: '',
      wholeName: '',
    })

    /**
     * reset 表单应用信息
     *
     * @description 将表单应用信息的各个字段重置为初始值
     * @returns 无返回值，直接修改全局变量 formAppInfo 的值
     */
    function resetFormAppInfo() {
      formAppInfo.key = generateRandomString()
      formAppInfo.alias = ''
      formAppInfo.packageName = ''
      formAppInfo.wholeName = ''
    }

    const handleAddSubmit = ({values, errors}) => {
      if (!errors) {
        addAppInfo()
      }
    }
    const handleEditSubmit = ({values, errors}) => {
      console.log('handleEditSubmit values: ', values)
      console.log('handleEditSubmit error: ', errors)
      if (!errors) {
        updateAppInfo()
      }
    }

    
    const isResultShow = ref(false)
    let testResult = ref(``)

    const processDevices = reactive({})
    const runAppStartTest = () => {
      if (selectedDeviceIds.value.length === 0) {
        Message.error({ content: 'Please select device!', duration: 2500})
        return
      }
      if (selectedApps.value.length === 0) {
        Message.error({ content: 'Please select app!', duration: 2500})
        return
      }
      // 初始化进度反馈所需的响应式数据
      selectedDeviceIds.value.forEach(sn => {
        processDevices[sn] = {
          totalProgress: 0,
          currentProgress: 0,
        }
      })

      isLogLayoutShowing.value = true
      xapi.adbAppStart(
        Array.from(selectedDeviceIds.value), 
        selectedApps.value.map(item => item.wholeName)
      )
      xapi.onStartLogBack(log => {
        appStartLogStore.append(log.device+ ', ' +log.log)

        processDevices[log.device].currentProgress += 0.2
        // 如果当前进度大于等于1，则延迟500ms，更新当前进度为0
        if (processDevices[log.device].currentProgress >= 1) {
          setTimeout(() => {
            processDevices[log.device].currentProgress = 0
          }, 500);
        }
      })

      xapi.onStartResultBack(result => {
        const strResult = JSON.stringify(result)
        testResult += strResult + '\n'
        appStartLogStore.append(strResult)
        processDevices[result.sn].currentProgress = 0
        processDevices[result.sn].totalProgress += 1/selectedApps.value.length
        setTimeout(() => {
          if (isTestOver()) {
            isLogLayoutShowing.value = false
            isResultShow.value = true
          }
        }, 1000);
      })
    }

    function isTestOver() {
      // 遍历processDevices，如果所有设备的totalProgress都大于等于1，则返回true
      for (const sn in processDevices) {
        const processDevice = processDevices[sn]
        console.log('processDevice: ', processDevice)
        if (processDevice.totalProgress < 1) {
          return false
        }
      }
      return true
    }

    const addAppInfo = () => {
      console.log('add to datebase')
      appInfoListStore.add(formAppInfo)
      isAddDialogShowing.value = false
    };

    const deleteAppInfo = (app) => {
      appInfoListStore.delete(app)
    }

    const updateAppInfo = () => {
      appInfoListStore.update(currentEditAppInfo)
      isEditDialogShowing.value = false
    }

    const deleteSelectByTag = (deleteApp) => {
      selectedKeys.value = selectedKeys.value.filter((item) => item !== deleteApp.key);
    }
</script>

<template>
    <a-drawer
      height="70%"
      :visible="isLogLayoutShowing"
      placement="bottom"
      :footer="false"
      :header="false"
      unmountOnClose
    >
      <div class="textarea-box">
        <div>App Start Test Process</div>
        <a-divider />
        <div v-for="device in selectedDeviceIds" :key="device" class="device-process-container">
          <div class="device-label">{{ device }} <a-progress :percent="processDevices[device].totalProgress" type="circle" size="mini" style="margin-left: 10px" /></div>
          <div class="progress-wrapper">
            <a-progress
              :percent="processDevices[device].currentProgress"
              :show-text="false"
              :style="{width: '400px', margin: '0 auto' }"
              :color="{
                '0%': 'rgb(var(--primary-6))',
                '100%': 'rgb(var(--success-6))',
              }"
            />
          </div>
        </div>
        <a-textarea class="textarea" :model-value="appStartLogStore.appStartLog" :closable="false" spellcheck="false"/>
      </div>
    </a-drawer>
    <a-card class="layout-start-test" title="App Start Test" hoverable>
        <template #extra>
          <a-button class="btn-run" type="primary" shape="round" status="success" @click="runAppStartTest">
            <icon-play-arrow :style="{fontSize:'20px'}"/>
          </a-button>
        </template>
        <div style="margin-bottom: 5px">Selected Apps:</div>
        <a-space wrap>
          <a-tag v-for="selectApp in selectedApps" :key="selectApp.packageName" closable @close="deleteSelectByTag(selectApp)" :color="'cyan'">{{ selectApp.alias }}</a-tag>
        </a-space>
    </a-card>
    <a-card id="dialog-parent" class="layout-start-app-info" title="App List" hoverable>
        <template #extra>
          <a-button class="btn-add" type="primary" shape="round" status="success" @click="showAddDialog()">
            <icon-plus :style="{fontSize:'20px'}"/>
          </a-button>
        </template>
        <a-table class="table"
          :data="data" 
          :stripe="true" 
          page-position="tr" 
          :row-Selection="{
            type: 'checkbox',
            showCheckedAll: true,
          }"
          v-model:selectedKeys="selectedKeys"
          :pagination="false"
          :virtual-list-props="{height:400}">
          <template #columns>
            <a-table-column title="Alias" data-index="alias" :width="120"></a-table-column>
            <a-table-column title="PackageName" data-index="packageName" :width="200"></a-table-column>
            <a-table-column title="WholeName" data-index="wholeName"></a-table-column>
            <a-table-column title="Optional" :width="100">
              <template #cell="{ record }">
                <a-button-group type="text" status="success">
                  <a-button @click="showEgitDialog(record)" >
                    <template #icon><icon-edit :style="{fontSize:'16px'}"/></template>
                  </a-button> 
                  <a-button @click="$modal.confirm({ 
                    title:'Delete App Info', 
                    content:'Are you sure you want to delete:  '+ record.alias + ' ?',
                    cancelText:'cancel',
                    okText: 'confirm',
                    onOk: () => deleteAppInfo(record),
                    })">
                    <template #icon><icon-delete :style="{fontSize:'16px'}"/></template>
                  </a-button>
                </a-button-group>
              </template>
            </a-table-column>
          </template>
        </a-table>
    </a-card>
    <a-modal width="auto" :modal-style="{ borderRadius: '15px' }" v-model:visible="isAddDialogShowing" :footer="false" hide-cancel draggable :closable="false" popup-container="#dialog-parent">
      <template #title>
        Add App Info
      </template>

      <a-form class="form" :model="formAppInfo" auto-label-width @submit="handleAddSubmit">
        <a-form-item field="alias" tooltip="Please named the app for yourself" label="alias"
          :rules="[{required:true,message:'alias is required'},{minLength:2,message:'must be greater than 2 characters'}]">
          <a-input
            v-model="formAppInfo.alias"
            placeholder="Please named the app for yourself"
          />
        </a-form-item>
        <a-form-item field="packageName" label="packageName"
          tooltip="If the list is empty, make sure that the device is selected on the home page and that the device is unlocked, then you can click the Reread button"
          :rules="[{required:true,message:'packageName is required'}]">
          <a-select v-model="formAppInfo.packageName" @change="packageChange" placeholder="Please select ..." allow-clear :loading="isAddSelectLoading">
            <a-option v-for="packageNameInfo in packageNameInfos">{{ packageNameInfo.packageName }}</a-option>
          </a-select>
        </a-form-item>
        <a-form-item field="wholeName" label="wholeName" disabled>
          <a-input
            v-model="formAppInfo.wholeName"
            placeholder="Please select above"
          />
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button @click="readPackageNames" type="secondary" shape="round" status="warning" :disabled="isAddSelectLoading">
              <template #icon>
                <icon-sync :spin="isAddSelectLoading"/>
              </template>
              Reread
            </a-button>
            <a-button html-type="submit" type="secondary" shape="round" status="success">
              <template #icon>
                <icon-save/>
              </template>
              Save
            </a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-modal>

    <a-modal width="auto" :modal-style="{ borderRadius: '15px' }" v-model:visible="isEditDialogShowing" :footer="false" hide-cancel draggable :closable="false" popup-container="#dialog-parent">
      <template #title>
        Edit App Info
      </template>

      <a-form class="form" :model="currentEditAppInfo" auto-label-width @submit="handleEditSubmit">
        <a-form-item field="alias" tooltip="Please named the app for yourself" label="alias"
          :rules="[{required:true,message:'alias is required'},{minLength:2,message:`must be greater than 2 characters`}]">
          <a-input
            v-model="currentEditAppInfo.alias"
            placeholder="Please named the app for yourself"
          />
        </a-form-item>
        <a-form-item field="packageName" label="packageName" disabled>
          <a-input
            v-model="currentEditAppInfo.packageName"
          />
        </a-form-item>
        <a-form-item field="wholeName" label="wholeName" disabled>
          <a-input
            v-model="currentEditAppInfo.wholeName"
          />
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button html-type="submit" type="secondary" shape="round" status="success">
              <template #icon>
                <icon-save/>
              </template>
              Save
            </a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-modal>

    <a-modal width="auto" :modal-style="{ borderRadius: '15px' }" v-model:visible="isResultShow" :footer="false" hide-cancel draggable :closable="false" popup-container="#dialog-parent">
      <a-result status="success" title="Test end!">
        <template #subtitle>
          {{ testResult }}
        </template>
        <template #extra>
          <a-space>
            <a-button type='primary' @click="() => isResultShow = false">Back</a-button>
          </a-space>
        </template>
      </a-result>
    </a-modal>
</template>

<style scoped>
.layout-start-test {
  border-radius: 10px;
  height: auto;
}
.textarea-box {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.device-process-container {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.progress-wrapper {
  text-align: center; 
  margin-bottom: 10px;
}
.textarea {
  flex: 1 1 auto; 
  resize: none; 
  line-height: 1.5;
  white-space: pre-line;
}

.layout-start-app-info {
  border-radius: 10px;
  margin-top: 10px;
}
.table {
  height: 400px;
}
.form {
  width: 80vw;
}
</style>